doc: Add some docs about adapting existing package managers
authorColin Walters <walters@verbum.org>
Sat, 24 Aug 2013 15:35:42 +0000 (11:35 -0400)
committerColin Walters <walters@verbum.org>
Sat, 24 Aug 2013 15:35:42 +0000 (11:35 -0400)
doc/Makefile.am
doc/adapting-existing.xml [new file with mode: 0644]
doc/atomic-upgrades.xml
doc/ostree-docs.xml

index 2748a70a448346a03ae5e70602a328c928f4a52e..edb0484332788ce8211bbaaffd14d2ad3f284de4 100644 (file)
@@ -78,6 +78,7 @@ content_files= \
        repo.xml \
        deployment.xml \
        atomic-upgrades.xml \
+       adapting-existing.xml \
        $(NULL)
 
 # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
diff --git a/doc/adapting-existing.xml b/doc/adapting-existing.xml
new file mode 100644 (file)
index 0000000..f651479
--- /dev/null
@@ -0,0 +1,204 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "../version.xml">
+]>
+<part id="adapting-existing">
+  <title>Adapating existing mainstream distributions</title>
+  <chapter id="layout">
+    <title>System layout</title>
+    <para>
+      First, OSTree encourages systems to implement <ulink
+      url="http://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/">UsrMove</ulink>.
+      This is simply to avoid the need for more bind mounts.  By
+      default OSTree's dracut hook creates a read-only bind mount over
+      <filename class='directory'>/usr</filename>; you can of course
+      generate individual bind-mounts for <filename
+      class='directory'>/bin</filename>, all the <filename
+      class='directory'>/lib</filename> variants, etc.  So it is not
+      intended to be a hard requirement.
+    </para>
+
+    <para>
+      The <filename class='directory'>/sysroot</filename> directory is
+      a new OS-level directory that OSTree expects to use as a bind
+      mount target to the physical <filename
+      class='directory'>/</filename> root directory.  Remember,
+      because by default the system is booted into a
+      <literal>chroot</literal> equivalent, there has to be some way
+      to refer to the actual physical root filesystem, and there is
+      precedent for this name in the initramfs context.  This
+      directory must exist; for example, the OSTree tool at runtime
+      expects that <filename
+      class='directory'>/sysroot/ostree/repo</filename> refers to the
+      system repository.
+    </para>
+
+    <para>
+      Because OSTree only preserves <filename
+      class='directory'>/var</filename> across upgrades, it is very
+      strongly recommended for systems which want to preserve
+      compatibility with the <ulink
+      url="http://www.pathname.com/fhs/">Filesystem Hierarchy
+      Standard</ulink> to create the following symbolic links:
+      <itemizedlist>
+       <listitem>
+         <para>
+          <filename class='directory'>/home</filename> to <filename class='directory'>/var/home</filename>
+         </para>
+        </listitem>
+       <listitem>
+         <para>
+           <filename class='directory'>/opt</filename> to <filename class='directory'>/var/opt</filename>
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           <filename class='directory'>/usr/local</filename> to <filename class='directory'>/var/local</filename>
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           <filename class='directory'>/mnt</filename> to <filename class='directory'>/var/mnt</filename>
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           <filename class='directory'>/tmp</filename> to <filename class='directory'>/sysroot/tmp</filename>
+         </para>
+       </listitem>
+      </itemizedlist>
+    </para>
+
+    <para>
+      Furthermore, since <filename class='directory'>/var</filename>
+      is empty by default, your operating system will need to
+      dynamically create these directories at boot.  A good way to do
+      this is using <command>systemd-tmpfiles</command>, if your OS
+      uses systemd.  For example:
+    </para>
+
+    <programlisting>
+      <![CDATA[
+d /var/log/journal 0755 root root -
+L /var/home - - - - ../sysroot/home
+d /var/opt 0755 root root -
+d /var/srv 0755 root root -
+d /var/roothome 0700 root root -
+d /var/usrlocal 0755 root root -
+d /var/usrlocal/bin 0755 root root -
+d /var/usrlocal/etc 0755 root root -
+d /var/usrlocal/games 0755 root root -
+d /var/usrlocal/include 0755 root root -
+d /var/usrlocal/lib 0755 root root -
+d /var/usrlocal/man 0755 root root -
+d /var/usrlocal/sbin 0755 root root -
+d /var/usrlocal/share 0755 root root -
+d /var/usrlocal/src 0755 root root -
+d /var/mnt 0755 root root -
+d /run/media 0755 root root -
+      ]]>
+</programlisting>
+  </chapter>
+
+  <chapter id="booting">
+    <title>Booting and initramfs technology</title>
+    <para>
+      OSTree comes with optional dracut+systemd integration code that
+      parses the <literal>ostree=</literal> kernel command line
+      argument in the initramfs, and then sets up the read-only bind
+      mount on <filename class='directory'>/usr</filename>, a bind
+      mount on the deployment's <filename
+      class='directory'>/sysroot</filename> to the physical <filename
+      class='directory'>/</filename>, and then finally uses
+      <literal>mount(MS_MOVE)</literal> to make the deployment root appear to be the
+      root filesystem before telling systemd to switch root.
+    </para>
+
+    <para>
+      If you are not using dracut or systemd, using OSTree should still
+      be possible, but you will have to write the integration code.  Patches
+      to support other initramfs technologies and init systems, if sufficiently
+      clean, will likely be accepted upstream.
+    </para>
+
+    <para>
+      A further specific note regarding <command>sysvinit</command>:
+      OSTree used to support recording device files such the
+      <filename>/dev/initctl</filename> FIFO, but no longer does.
+      It's recommended to just patch your initramfs to create this at
+      boot.
+    </para>
+  </chapter>
+
+  <chapter id="adapting-package-manager">
+    <title>Adapting existing package managers</title>
+    <para>
+      The largest endeavor is likely to be redesigning your
+      distribution's package manager to be on top of OSTree,
+      particularly if you want to keep compatibility with the "old
+      way" of installing into the physical <filename
+      class='directory'>/</filename>.  This section will use examples
+      from both <command>dpkg</command> and <command>rpm</command> as
+      the author has familiarity with both; but the abstract concepts
+      should apply to most traditional package managers.
+    </para>
+
+    <para>
+      There are many levels of possible integration; initially, we
+      will describe the most naive implementation which is the
+      simplest but also the least efficient.  We will assume here that
+      the admin is booted into an OSTree-enabled system, and wants to
+      add a set of packages.
+    </para>
+
+    <para>
+      Many package managers store their state in <filename
+      class='directory'>/var</filename>; but since in the OSTree model
+      that directory is shared between independent versions, the
+      package database must first be found in the per-deployment
+      <filename class='directory'>/usr</filename> directory.  It
+      becomes read-only; remember, all upgrades involve constructing a
+      new filesystem tree, so your package manager will also need to
+      create a copy of its database.  Most likely, if you want to
+      continue supporting non-OSTree deployments, simply have your
+      package manager fall back to the legacy <filename
+      class='directory'>/var</filename> location if the one in
+      <filename class='directory'>/usr</filename> is not found.
+    </para>
+
+    <para>
+      To install a set of new packages (without removing any existing
+      ones), enumerate the set of packages in the currently booted
+      deployment, and perform dependency resolution to compute the
+      complete set of new packages.  Download and unpack these new
+      packages to a temporary directory.
+    </para>
+
+    <para>
+      Now, because we are merely installing new packages and not
+      removing anything, we can make the major optimization of reusing
+      our existing filesystem tree, and merely
+      <emphasis>layering</emphasis> the composed filesystem tree of
+      these new packages on top.  A command lke this: <command>ostree
+      commit -b osname/releasename/description
+      --tree=ref=<replaceable>osname/releasenamename/description</replaceable>
+      --tree=dir=/var/tmp/newpackages.13A8D0/</command> will create a
+      new commit in the
+      <replaceable>osname/releasename/description</replaceable>
+      branch.  The OSTree SHA256 checksum of all the files in
+      /var/tmp/newpackages.13A8D0/ will be computed, but we will not
+      re-checksum the present existing tree.  In this layering model,
+      earlier directories will take precedence, but files in later
+      layers will silently override earlier layers.
+    </para>
+
+    <para>
+      Then to actually deploy this tree for the next boot:
+      <command>ostree admin deploy
+      <replaceable>osname/releasenamename/description</replaceable></command>
+    </para>
+      
+  </chapter>
+
+</part>
index 9fb203047a8f9117ba3dfc85aab26b6bb9f3bd64..1a1be839cce2d0cb60b9086b3844b33e1f6978ce 100644 (file)
       "live" on the currently booted filesystem.  The way they could
       work with OSTree is instead to take the list of installed
       packages in the currently booted tree, and compute a new
-      filesystem from that.
+      filesystem from that.  A later chapter describes in more details
+      how this could work: <xref linkend="adapting-existing"/>.
     </para>
 
     <para>
-      The most basic implementation of this would be something like
-      taking the result of <command>rpm -qa</command>, and doing
-      <command>yum --installroot=/var/tmp/newroot install
-      <replaceable>package1</replaceable>
-      <replaceable>package2</replaceable> ...</command>.  Then,
-      <command>ostree commit -b osname/localtree
-      --tree=dir=/var/tmp/newroot</command>.  This would checksum all
-      of the input files and store them in local <filename
-      class='directory'>/ostree/repo</filename> repository, creating
-      a new commit.
-    </para>
-
-    <para>
-      Now, we can move on to deployment.
+      For the purposes of this section, let's assume that we have a
+      newly generated filesystem tree stored in the repo (which shares
+      storage with the existing booted tree).  We can then move on to
+      checking it back out of the repo into a deployment.
     </para>
   </chapter>
 
index cf953c1364b1cad79b0e53cadf867f4ee7954f24..ba6e7cdd19f04b3ba30c3d5f67d6a68773eefbc3 100644 (file)
@@ -15,6 +15,7 @@
        <xi:include href="repo.xml"/>
        <xi:include href="deployment.xml"/>
        <xi:include href="atomic-upgrades.xml"/>
+       <xi:include href="adapting-existing.xml"/>
 
        <chapter xml:id="reference">
                <title>API Reference</title>